﻿using System;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;
using Polly;
using Polly.Timeout;

namespace PollyTest1
{
    class Program
    {
        static void Main(string[] args)
        {
            /*
            try
            {
                Policy policy = Policy.Handle<ArgumentException>()
                    .Fallback(() =>
                    {
                        Console.WriteLine("参数异常！");
                    });

                policy.Execute(() =>
                {
                    Console.WriteLine("业务处理开始！");

                    throw new ArgumentException();

                    Console.WriteLine("业务处理结束！");
                });

            }
            catch (Exception exp)
            {
                Console.WriteLine("发生未处理异常");
            }
            */

            /*
            try
            {
                Policy<string> policy = Policy<string>.Handle<ArgumentException>()
                        .Fallback(() =>
                        {
                            Console.WriteLine("Fallback");
                            return "备用通道处理完";
                        });

                var result = policy.Execute(() =>
                {
                    Console.WriteLine("开始处理");
                    throw new ArgumentException();
                    Console.WriteLine("处理结果");
                    return "主通道处理完成";
                });


                Console.WriteLine(result);
            }
            catch (Exception exp)
            {
                Console.WriteLine("未处理异常");
            }
            */

            /*
            Policy policy = Policy.Handle<Exception>().WaitAndRetry(3, (i) =>
            {
                Console.WriteLine($"重试:{i}");

                return TimeSpan.FromSeconds(i);
            });

            policy.Execute(() =>
            {
                Console.WriteLine("业务处理开始");

                if (DateTime.Now.Second % 10 != 0)
                {
                    throw new Exception();
                }

                Console.WriteLine("业务处理结束");
            });
            */

            /*
            Policy policy = Policy.Handle<Exception>().CircuitBreaker(3, TimeSpan.FromSeconds(5));

            while (true)
            {
                Console.WriteLine("SETP1:Execute执行开始");

                try
                {
                    policy.Execute(() =>
                    {
                        Console.WriteLine("STEP2:业务执行开始");

                        throw new Exception();

                        Console.WriteLine("业务执行结束");
                    });
                }
                catch (Exception exp)
                {
                    Console.WriteLine($"STEP3:ExecuteExp:{exp.Message}");
                }

                Thread.Sleep(500);
            }
            
             */

            PollyAsync();

            Console.ReadKey();
        }

        static async Task PollyAsync()
        {
            Policy<byte[]> policy = Policy<byte[]>.Handle<Exception>()
                .FallbackAsync(async x =>
                {
                    Console.WriteLine("Fallback");
                    return new byte[0];
                }, async y =>
                {
                    Console.WriteLine(y.Exception.Message);
                });

            policy = policy.WrapAsync(Policy.TimeoutAsync(2, TimeoutStrategy.Pessimistic, async (context, timeSpan, task) =>
            {
                Console.WriteLine("Timeout");
            }));

            var bytes = await policy.ExecuteAsync(async () =>
            {
                Console.WriteLine("业务执行开始");

                var result = new byte[0];

                using (var httpClient = new HttpClient())
                {
                    result = await httpClient.GetByteArrayAsync("http://static.rupeng.com/upload/chatimage/20183/07EB793A4C247A654B31B4D14EC64BCA.png");
                }

                Console.WriteLine("业务执行结束");

                return result;
            });

            Console.WriteLine($"业务执行结果：{bytes.Length}");
        }
    }
}
